package org.jeecg.modules.scm.service.impl;

import cfca.trustsign.common.vo.cs.CreateContractVO;
import cfca.trustsign.common.vo.cs.SignInfoVO;
import cfca.trustsign.demo.op.CfcaOp;
import cfca.trustsign.demo.util.TimeUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.URLUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.seata.spring.annotation.GlobalTransactional;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.system.api.ISysBaseAPI;
import org.jeecg.common.system.base.entity.LoginOrganization;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.CommonUtils;
import org.jeecg.common.util.UUIDGenerator;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.modules.flow.api.FlowBaseCloudApi;
import org.jeecg.modules.flow.query.*;
import org.jeecg.modules.flow.vo.*;
import org.jeecg.modules.scm.constant.ScmConstant;
import org.jeecg.modules.scm.dto.ScmReceivablesTransferApplicationDto;
import org.jeecg.modules.scm.dto.TransferApplicationQueryPageDto;
import org.jeecg.modules.scm.entity.*;
import org.jeecg.modules.scm.mapper.*;
import org.jeecg.modules.scm.service.IScmCusDeputyProtocolService;
import org.jeecg.modules.scm.service.IScmReceivablesTransferApplicationService;
import org.jeecg.modules.scm.vo.ScmReceivablesTransferApplicationVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;

/**
 * @Description: scm_receivables_transfer_application
 * @Author: jeecg-boot
 * @Date: 2021-11-09
 * @Version: V1.0
 */
@Service
@Slf4j
public class ScmReceivablesTransferApplicationServiceImpl extends ServiceImpl<ScmReceivablesTransferApplicationMapper, ScmReceivablesTransferApplication> implements IScmReceivablesTransferApplicationService {

    @Resource
    ScmReceivablesTransferApplicationMapper scmReceivablesTransferApplicationMapper;
    @Resource
    ScmCloudChainTransferApplicationMapper scmCloudChainTransferApplicationMapper;
    @Resource
    ScmReceivablesTransferContractMapper scmReceivablesTransferContractMapper;
    @Resource
    ScmCloudChainTransferContractMapper scmCloudChainTransferContractMapper;
    @Resource
    ScmCloudChainMapper scmCloudChainMapper;
    @Autowired
    private FlowBaseCloudApi flowBaseCloudApi;
    @Autowired
    private IScmCusDeputyProtocolService scmCusDeputyProtocolService;
    @Resource
    private ScmCusInfoMapper scmCusInfoMapper;
    @Resource
    private ISysBaseAPI sysBaseAPI;


    @Override
    public String uploadContract(MultipartFile file) {
        String url = CommonUtils.upload(file, "/receivablesTransfer/contract", CommonConstant.UPLOAD_TYPE_MINIO);
        String path = URLUtil.getPath(url);
        return path;
    }

    @Override
    @Transactional
    public Result<?> editApplication(ScmReceivablesTransferApplicationDto applicationDto) {
        Result<String> result = new Result<>();
        LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        List<ScmCloudChain> oldChainList = findCloudChain(applicationDto.getId());
        //将申请关联的云链单状态改回原来状态
        for (ScmCloudChain scmCloudChain : oldChainList) {
            if (oConvertUtils.isEmpty(scmCloudChain.getOriginalChainNo())) {
                scmCloudChain.setStauts(ScmConstant.CHAIN_STATUS_NORMAL);
            } else {
                scmCloudChain.setStauts(ScmConstant.CHAIN_STATUS_SPLIT);
            }
            scmCloudChainMapper.updateById(scmCloudChain);
        }
        LambdaQueryWrapper<ScmCloudChain> chainNosWrapper = new LambdaQueryWrapper<>();
        chainNosWrapper.in(ScmCloudChain::getChainNo, applicationDto.getCloudChianNos());
        List<ScmCloudChain> scmCloudChainList = scmCloudChainMapper.selectList(chainNosWrapper);
        basicCheck(applicationDto, user, scmCloudChainList);

        ScmReceivablesTransferApplication application = new ScmReceivablesTransferApplication();
        BeanUtils.copyProperties(applicationDto, application);
        //设置申请时间为当前时间
        application.setApplyTime(new Date());
        scmReceivablesTransferApplicationMapper.updateById(application);

        processChain(applicationDto, scmCloudChainList, application.getId(), result);

        String instanceId = "";
        if (applicationDto.getStatus().equals(ScmConstant.RECEIVABLES_TRANSFER_STATUS_INPROCESS)) {
            //放入转让流程
            Result<String> flowResult = startInstance(applicationDto, user, application.getId());
            instanceId = flowResult.getResult();
            result.setMessage(result.getMessage() + "提交审批成功！");
        }
        result.setSuccess(true);
        result.setCode(CommonConstant.SC_OK_200);
        result.setResult(instanceId);
        return result;
    }

    @Override
    @Transactional
    @GlobalTransactional
    public Result<?> saveScmReceivablesTransferApplication(ScmReceivablesTransferApplicationDto applicationDto) {
        Result<String> result = new Result<>();
        LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        LambdaQueryWrapper<ScmCloudChain> chainNosWrapper = new LambdaQueryWrapper<>();
        chainNosWrapper.in(ScmCloudChain::getChainNo, applicationDto.getCloudChianNos());
        List<ScmCloudChain> scmCloudChainList = scmCloudChainMapper.selectList(chainNosWrapper);

        basicCheck(applicationDto, user, scmCloudChainList);

        ScmReceivablesTransferApplication application = new ScmReceivablesTransferApplication();
        BeanUtils.copyProperties(applicationDto, application);
        application.setId(UUIDGenerator.generate());
        //设置申请时间为当前时间
        application.setApplyTime(new Date());
        //保存申请表
        scmReceivablesTransferApplicationMapper.insert(application);

        processChain(applicationDto, scmCloudChainList, application.getId(), result);

        String instanceId = "";
        if (applicationDto.getStatus().equals(ScmConstant.RECEIVABLES_TRANSFER_STATUS_INPROCESS)) {
            //放入转让流程
            Result<String> flowResult = startInstance(applicationDto, user, application.getId());
            instanceId = flowResult.getResult();
            result.setMessage(result.getMessage() + "提交审批成功！");
        }
        result.setSuccess(true);
        result.setCode(CommonConstant.SC_OK_200);
        result.setResult(instanceId);
        return result;
    }

    void basicCheck(ScmReceivablesTransferApplicationDto applicationDto, LoginUser user, List<ScmCloudChain> scmCloudChainList) {
        //检查转让人与受让人是否不相同
        if (applicationDto.getOwnerCusNo().equals(applicationDto.getTransfereeCusNo())) {
            throw new JeecgBootException("转让人与受让人不能相同！");
        }
        //判断当前用户是否属于平台端
        if (user.getOrganization().getType().equals(ScmConstant.ORG_TYPE_PLATFORM)) {
            //检查该平台用户是否同转让人签署代客协议
            LambdaQueryWrapper<ScmCusDeputyProtocol> cusDeputyWrapper = new LambdaQueryWrapper<>();
            cusDeputyWrapper.eq(ScmCusDeputyProtocol::getCusNo, user.getCusNo())
                    .eq(ScmCusDeputyProtocol::getCoreCusNo, applicationDto.getOwnerCusNo());
            ScmCusDeputyProtocol scmCusDeputyProtocol = scmCusDeputyProtocolService.getOne(cusDeputyWrapper);
            if (oConvertUtils.isNotEmpty(scmCusDeputyProtocol)) {
                throw new JeecgBootException("请先签署代客协议！");
            }
        } else {
            if (!user.getCusNo().equals(applicationDto.getOwnerCusNo())) {
                throw new JeecgBootException("不可以转让其他客户的应收账款！");
            }
        }
        for (ScmCloudChain scmCloudChain : scmCloudChainList) {
            if (!applicationDto.getOwnerCusNo().equals(scmCloudChain.getOwnerCusNo())) {
                throw new JeecgBootException(scmCloudChain.getOwnerCusNo() + "非本转让人拥有的云链单！");
            }
        }
    }

    void processChain(ScmReceivablesTransferApplicationDto applicationDto, List<ScmCloudChain> scmCloudChainList, String applicationId, Result<String> result) {
        //检查云链单与金额汇总
        Result<Integer> checkResult = checkAmount("start", applicationDto.getTransferAmount(), scmCloudChainList);
        Integer checkInteger = checkResult.getResult();
        //检查云链单不通过
        if (!checkInteger.equals(0) && !checkInteger.equals(-1)) {
            throw new JeecgBootException(checkResult.getMessage());
        }
        result.setMessage(checkResult.getMessage());
        List<ScmCloudChain> cloudChainList = new ArrayList<>();
        //云链单金额汇总大于转让金额
        if (checkInteger.equals(-1)) {
            //将云链单进行拆分
            Result<List<ScmCloudChain>> splitResult = splitCloudChain("start", applicationDto.getTransferAmount(), scmCloudChainList);
            //返回申请关联云链单实例对象集合
            cloudChainList = splitResult.getResult();
            result.setMessage(result.getMessage() + splitResult.getMessage());
        }
        //云链单金额汇总等于转让金额
        if (checkInteger.equals(0)) {
            //获取申请关联云链单实例对象集合
            LambdaQueryWrapper<ScmCloudChain> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.in(ScmCloudChain::getChainNo, applicationDto.getCloudChianNos());
            cloudChainList = scmCloudChainMapper.selectList(queryWrapper);
        }

        //保存关联云链单
        for (ScmCloudChain scmCloudChain : cloudChainList) {
            //将云链单状态设置为转让中
            scmCloudChain.setStauts(ScmConstant.CHAIN_STATUS_INTRANSFER);
            scmCloudChainMapper.updateById(scmCloudChain);
            ScmCloudChainTransferApplication cloudChainTransferApplication = new ScmCloudChainTransferApplication(applicationId, scmCloudChain.getChainNo());
            scmCloudChainTransferApplicationMapper.insert(cloudChainTransferApplication);
        }
    }

    Result<String> startInstance(ScmReceivablesTransferApplicationDto applicationDto, LoginUser user, String applicationId) {
        StartInstanceQuery query = new StartInstanceQuery();
        Map<String, Object> var = new HashMap<>();
        query.setVariables(var);
        query.setProcessKey("receivables_transfer");
        query.setOrgId(user.getOrganization().getOrganizationId());
        query.setCusNo(applicationDto.getOwnerCusNo());
        query.setName(user.getUsername() + "-应收账款转让-" + DateUtil.date());
        // 根据自己的业务需求设置
        query.setBusinessKey("receivables_transfer:" + applicationId);
        // 调用流程服务，启动流程实例
        Result<String> flowResult = flowBaseCloudApi.startInstanceByProKey(query);
        if (!flowResult.getCode().equals(200)) {
            throw new JeecgBootException("您无权提交审批！");
        }
        return flowResult;
    }

    public Result<Integer> checkAmount(String type, BigDecimal transferAmount, List<ScmCloudChain> scmCloudChainList) {
        BigDecimal selectAmount = new BigDecimal(0);
        for (ScmCloudChain scmCloudChain : scmCloudChainList) {
            if ("start".equals(type)) {
                if (scmCloudChain.getStauts().equals(ScmConstant.CHAIN_STATUS_INVALID)) {
                    return Result.error("云链单：" + scmCloudChain.getChainNo() + " 已失效！", 2);
                }
                if (scmCloudChain.getStauts().equals(ScmConstant.CHAIN_STATUS_OVERDUE)) {
                    return Result.error("云链单：" + scmCloudChain.getChainNo() + " 已过期！", 3);
                }
                if (scmCloudChain.getStauts().equals(ScmConstant.CHAIN_STATUS_INFINANCING)) {
                    return Result.error("云链单：" + scmCloudChain.getChainNo() + " 正在融资申请中！", 4);
                }
                if (scmCloudChain.getStauts().equals(ScmConstant.CHAIN_STATUS_FINANCED)) {
                    return Result.error("云链单：" + scmCloudChain.getChainNo() + " 已融资！", 5);
                }
                if (scmCloudChain.getStauts().equals(ScmConstant.CHAIN_STATUS_INTRANSFER)) {
                    return Result.error("云链单：" + scmCloudChain.getChainNo() + " 正在转让中！", 6);
                }
            }
            selectAmount = selectAmount.add(scmCloudChain.getAmount());
        }
        if (transferAmount.compareTo(selectAmount) == 1) {
            return Result.error("所选云链单总金额小于于转让金额！", 1);
        } else if (transferAmount.compareTo(selectAmount) == -1) {
            return Result.OK("所选云链单总金额大于转让金额！", -1);
        } else {
            return Result.OK("转让金额等于所选云链单总金额！", 0);
        }
    }

    @Transactional(rollbackFor = Exception.class)
    public Result<List<ScmCloudChain>> splitCloudChain(String type, BigDecimal transferAmount, List<ScmCloudChain> scmCloudChainList) {
        BigDecimal selectAmount = new BigDecimal(0);
        //计算所选云链单金额总金额
        for (ScmCloudChain scmCloudChain : scmCloudChainList) {
            selectAmount = selectAmount.add(scmCloudChain.getAmount());
        }
        //计算总金额与转让金额差，即云链单金额汇总超出转让金额的超出金额
        BigDecimal spareAmount = selectAmount.subtract(transferAmount);
        ScmCloudChain splitCloudChain1 = new ScmCloudChain();
        //标记是否选出要拆分云链单
        boolean splitSelected = false;
        //自动选择要拆分云链单
        for (ScmCloudChain scmCloudChain : scmCloudChainList) {
            //云链单金额大于超出金额
            if (scmCloudChain.getAmount().compareTo(spareAmount) == 1) {
                //选择该云链单为要拆分云链单
                splitCloudChain1 = scmCloudChain;
                splitSelected = true;
                break;
            }
            //云链单金额等于超出金额
            if (scmCloudChain.getAmount().compareTo(spareAmount) == 0) {
                //将该云链单移出申请所关联云链单列表
                scmCloudChainList.remove(scmCloudChain);
                return Result.OK("已去除多余云链单！", scmCloudChainList);
            }
        }
        if ("start".equals(type) && splitSelected) {
            return Result.OK("云链单在审批通过后将被拆分！", scmCloudChainList);
        }
        //云链单金额即不等于也不大于超出金额
        if (!splitSelected) {
            for (ScmCloudChain scmCloudChain : scmCloudChainList) {
                //云链单金额大于超出金额
                if (scmCloudChain.getAmount().compareTo(spareAmount) == 1) {
                    splitCloudChain1 = scmCloudChain;
                    splitSelected = true;
                    break;
                }
                //云链单金额小于超出金额
                if (scmCloudChain.getAmount().compareTo(spareAmount) == -1) {
                    spareAmount = spareAmount.subtract(scmCloudChain.getAmount());
                    //将该云链单移出申请所关联云链单列表
                    scmCloudChainList.remove(scmCloudChain);
                    continue;
                }
                //云链单金额等于超出金额
                if (scmCloudChain.getAmount().compareTo(spareAmount) == 0) {
                    spareAmount = spareAmount.subtract(scmCloudChain.getAmount());
                    //将该云链单移出申请所关联云链单列表
                    scmCloudChainList.remove(scmCloudChain);
                    break;
                }
            }
        }
        if (spareAmount.compareTo(new BigDecimal(0)) == 0) {
            return Result.OK("已去除多余云链单！", scmCloudChainList);
        }
        if ("start".equals(type) && splitSelected) {
            return Result.OK("已去除多余云链单！云链单在审批通过后将被拆分！", scmCloudChainList);
        }
        ScmCloudChain splitCloudChain2 = new ScmCloudChain();
        //原始交易合同金额改为云链单当前金额
        splitCloudChain1.setOriginalContractAmount(splitCloudChain1.getAmount());
        //当前凭证金额=当前凭证金额-超出金额
        splitCloudChain1.setAmount(splitCloudChain1.getAmount().subtract(spareAmount));
        //拆分前凭证编号改为当前凭证编号
        splitCloudChain1.setParentChainNo(splitCloudChain1.getChainNo());
        //上一手持有人客户号改为当前持有人客户号
        splitCloudChain1.setPreOwnerCusNo(splitCloudChain1.getOwnerCusNo());
        //原始交易合同币种改为当前凭证币种
        splitCloudChain1.setOriginalContractCurrency(splitCloudChain1.getCurrency());
        BeanUtils.copyProperties(splitCloudChain1, splitCloudChain2);
        //拆分出的云链单状态设为已拆分
        splitCloudChain2.setStauts(ScmConstant.CHAIN_STATUS_SPLIT);
        //拆分出的云链单凭证金额设为超出金额
        splitCloudChain2.setAmount(spareAmount);
        //拆分出的云链单设置新的凭证编号
        splitCloudChain2.setChainNo(UUID.randomUUID().toString().replace("-", ""));
        scmCloudChainMapper.updateById(splitCloudChain1);
        scmCloudChainMapper.insert(splitCloudChain2);
        return Result.OK("云链单已进行拆分！", scmCloudChainList);
    }

    /**
     * 查找申请关联云链单
     *
     * @param id 申请ID
     * @return
     */
    @Override
    public List<ScmCloudChain> findCloudChain(String id) {
        LambdaQueryWrapper<ScmCloudChainTransferApplication> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ScmCloudChainTransferApplication::getTransferApplyId, id);
        List<ScmCloudChainTransferApplication> list = scmCloudChainTransferApplicationMapper.selectList(queryWrapper);
        List<ScmCloudChain> scmCloudChainList = new ArrayList<>();
        for (ScmCloudChainTransferApplication s : list) {
            ScmCloudChain scmCloudChain = scmCloudChainMapper.selectById(s.getChainNo());
            scmCloudChainList.add(scmCloudChain);
        }
        return scmCloudChainList;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Map<String, List<String>> approveBatch(List<String> transferApplyIds) {
        Map<String, List<String>> map = new HashMap<>();
        //不是申请中的申请列表
        List<String> notInApplicationList = new ArrayList<>();
        //无权提交审批的申请列表
        List<String> noRightList = new ArrayList<>();
        //成功提交审批的申请列表
        List<String> successList = new ArrayList<>();
        LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        LoginOrganization organization = user.getOrganization();
        for (String transferApplyId : transferApplyIds) {
            ScmReceivablesTransferApplication scmReceivablesTransferApplication = scmReceivablesTransferApplicationMapper.selectById(transferApplyId);
            //状态不是申请中的申请
            if (!scmReceivablesTransferApplication.getStatus().equals(ScmConstant.RECEIVABLES_TRANSFER_STATUS_INAPPLICATION)) {
                notInApplicationList.add(transferApplyId);
                continue;
            }
            //放入转让流程
            Map<String, Object> variables = new HashMap<>();
            StartInstanceQuery query = new StartInstanceQuery();
            query.setProcessKey("receivables_transfer");
            query.setName(user.getUsername() + "-应收账款转让-" + DateUtil.date());
            query.setOrgId(organization.getOrganizationId());
            query.setCusNo(scmReceivablesTransferApplication.getOwnerCusNo());
            query.setBusinessKey("receivables_transfer:" + scmReceivablesTransferApplication.getId());
            query.setVariables(variables);
            // 调用流程服务，启动流程实例
            Result<String> result = flowBaseCloudApi.startInstanceByProKey(query);
            //无权提交审批的申请
            if (result.getCode() != 200) {
                noRightList.add(transferApplyId);
                continue;
            }
            //更新申请表状态为流程中
            LambdaUpdateWrapper<ScmReceivablesTransferApplication> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
            lambdaUpdateWrapper.eq(ScmReceivablesTransferApplication::getId, scmReceivablesTransferApplication.getId()).set(ScmReceivablesTransferApplication::getStatus, ScmConstant.RECEIVABLES_TRANSFER_STATUS_INPROCESS);
            scmReceivablesTransferApplicationMapper.update(null, lambdaUpdateWrapper);
            successList.add(transferApplyId);
        }
        map.put("notInApplicationList", notInApplicationList);
        map.put("noRightList", noRightList);
        map.put("successList", successList);
        return map;
    }

    @Override
    @GlobalTransactional
    public Result<?> handleTask(SubmitTaskQuery query) {
        Result<?> result = Result.OK();
        Boolean submitResult = (Boolean) flowBaseCloudApi.submitTask(query).getResult();
        result.setMessage("处理成功！");
        ProInstanceVo proInstanceVo = flowBaseCloudApi.searchInstanceById(query.getInstanceId()).getResult();
        //流程在第一个节点被退回或被终结
        if ((query.getSubmitType().equals(2) || query.getSubmitType().equals(3)) && oConvertUtils.isEmpty(proInstanceVo)) {
            ScmReceivablesTransferApplication application = scmReceivablesTransferApplicationMapper.selectById(query.getBusinessKey().split(":")[1]);
            application.setStatus(ScmConstant.RECEIVABLES_TRANSFER_STATUS_INAPPLICATION);
            scmReceivablesTransferApplicationMapper.updateById(application);
        }
        HistoryInstanceQuery historyInstanceQuery = new HistoryInstanceQuery();
        historyInstanceQuery.setProcessInstanceId(query.getInstanceId());
        HistoryProcessInstanceVo historyProcessInstanceVo = flowBaseCloudApi.queryHistoricProcessInstances(historyInstanceQuery, 0, Integer.MAX_VALUE).getResult().getRecords().get(0);
        //流程结束
        if (query.getSubmitType().equals(1) && oConvertUtils.isNotEmpty(historyProcessInstanceVo.getEndTime())) {
            String applicationId = query.getBusinessKey().split(":")[1];
            ScmReceivablesTransferApplication s = scmReceivablesTransferApplicationMapper.selectById(applicationId);
            //获取申请关联的云链单
            List<ScmCloudChain> cloudChainList = findCloudChain(s.getId());
            //检查云链单
            Integer checkResult = checkAmount("end", s.getTransferAmount(), cloudChainList).getResult();
            if (checkResult.equals(-1)) {
                Result<List<ScmCloudChain>> splitResult = splitCloudChain("end", s.getTransferAmount(), cloudChainList);
                result.setMessage(result.getMessage() + splitResult.getMessage());
            }
            //创建合同
            JSONObject cfcaContractResult = createCfcaContract(s);
            if (oConvertUtils.isNotEmpty(cfcaContractResult.getString("errorMessage"))) {
                return Result.error(cfcaContractResult.getString("errorMessage"));
            }
            String cfcaContractNo = cfcaContractResult.getJSONObject("contract").getString("contractNo");

            generateContract(s, cfcaContractNo);

        }
        if (submitResult) {
            return result;
        } else {
            return Result.error("处理失败！");
        }
    }

    @Override
    public Result<?> queryProgress(HistoryActivityQuery query) {
        Result<Page<HistoryActivityInstanceVo>> result = flowBaseCloudApi.queryHistoricActivityInstance(query, 0, Integer.MAX_VALUE);
        return result;
    }

    @Transactional(rollbackFor = Exception.class)
    public JSONObject createCfcaContract(ScmReceivablesTransferApplication s) {
        ScmCusInfo transferor = scmCusInfoMapper.selectById(s.getOwnerCusNo());
        ScmCusInfo transferee = scmCusInfoMapper.selectById(s.getTransfereeCusNo());
        String transferorUserId = "";
        String transfereeUserId = "";
        JSONObject transferorResult = JSONObject.parseObject(CfcaOp.getCus(transferor.getCusName(), transferor.getCertificateType(), transferor.getCertificateNo()));
        JSONObject transferorHead = transferorResult.getJSONObject("head");
        log.info(transferorResult.toString());
        if (transferorHead != null && "60000000".equals(transferorHead.getString("retCode"))) {
            transferorUserId = transferorResult.getJSONObject("userInfo").getString("userId");
        } else {
            return transferorResult;
        }
        JSONObject transfereeResult = JSONObject.parseObject(CfcaOp.getCus(transferee.getCusName(), transferee.getCertificateType(), transferee.getCertificateNo()));
        JSONObject transfereeHead = transfereeResult.getJSONObject("head");
        if (transfereeHead != null && "60000000".equals(transfereeHead.getString("retCode"))) {
            transfereeUserId = transfereeResult.getJSONObject("userInfo").getString("userId");
        } else {
            return transfereeResult;
        }

        CreateContractVO createContract = new CreateContractVO();
        Map<String, String> fieldMap = new HashMap<String, String>();

        createContract.setTemplateId("ZY_1826");
        createContract.setContractName("应收账款转让合同");
        createContract.setIsSign(1);
        fieldMap.put("transferor_name", transferor.getCusName());
        fieldMap.put("transferee_name", transferee.getCusName());
        fieldMap.put("transfer_amount", s.getTransferAmount().toString());

        createContract.setTextValueInfo(fieldMap);
        createContract.setIsSaveTextValue(1);
        createContract.setIsFillInFont(1);

        SignInfoVO[] signInfos = new SignInfoVO[2];
        SignInfoVO signInfoVO0 = new SignInfoVO();
        signInfoVO0.setUserId(transferorUserId);
        signInfoVO0.setIsProxySign(0);
        signInfoVO0.setLocation("211.94.108.226");
        signInfoVO0.setProjectCode("003");
        signInfoVO0.setSignLocation("transferor_sign");
        signInfoVO0.setAuthorizationTime(TimeUtil.getCurrentTime(TimeUtil.FORMAT_14));
        signInfos[0] = signInfoVO0;
        SignInfoVO signInfoVO1 = new SignInfoVO();
        signInfoVO1.setUserId(transfereeUserId);
        signInfoVO1.setIsProxySign(0);
        signInfoVO1.setLocation("211.94.108.226");
        signInfoVO1.setProjectCode("003");
        signInfoVO1.setSignLocation("transferee_sign");
        signInfoVO1.setAuthorizationTime(TimeUtil.getCurrentTime(TimeUtil.FORMAT_14));
        signInfos[1] = signInfoVO1;
        createContract.setSignInfos(signInfos);
        String s1 = CfcaOp.createContract(createContract);
        return JSONObject.parseObject(s1);
    }

    @Transactional(rollbackFor = Exception.class)
    public void generateContract(ScmReceivablesTransferApplication scmReceivablesTransferApplication, String cfcaContractNo) {
        //通过申请表id查找要生成合同的申请表
        LambdaUpdateWrapper<ScmReceivablesTransferApplication> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        lambdaUpdateWrapper.eq(ScmReceivablesTransferApplication::getId, scmReceivablesTransferApplication.getId())
                .set(ScmReceivablesTransferApplication::getStatus, ScmConstant.RECEIVABLES_TRANSFER_STATUS_TOBESIGNED);
        //更新申请表状态为未签约
        scmReceivablesTransferApplicationMapper.update(null, lambdaUpdateWrapper);
        ScmReceivablesTransferContract scmReceivablesTransferContract = new ScmReceivablesTransferContract();
        //将申请表中与合同表相同的字段复制到合同
        BeanUtils.copyProperties(scmReceivablesTransferApplication, scmReceivablesTransferContract);
        //设置id
        scmReceivablesTransferContract.setId(UUID.randomUUID().toString().replace("-", ""));
        //设置CFCA合同编号
        scmReceivablesTransferContract.setCfcaContractNo(cfcaContractNo);
        //设置申请号
        scmReceivablesTransferContract.setTransferApplyId(scmReceivablesTransferApplication.getId());
        //设置转让人
        scmReceivablesTransferContract.setTransferorCusNo(scmReceivablesTransferApplication.getOwnerCusNo());
        //设置合同状态为未签约
        scmReceivablesTransferContract.setStatus(ScmConstant.RECEIVABLES_CONTRACT_STATUS_NOTSIGNED);
        scmReceivablesTransferContractMapper.insert(scmReceivablesTransferContract);
        LambdaQueryWrapper<ScmCloudChainTransferApplication> transferQueryWrapper = new LambdaQueryWrapper<>();
        transferQueryWrapper.eq(ScmCloudChainTransferApplication::getTransferApplyId, scmReceivablesTransferApplication.getId());
        //查询申请关联的云链单
        List<ScmCloudChainTransferApplication> scmCloudChainTransferApplicationList = scmCloudChainTransferApplicationMapper.selectList(transferQueryWrapper);
        for (ScmCloudChainTransferApplication s : scmCloudChainTransferApplicationList) {
            ScmCloudChainTransferContract scmCloudChainTransferContract = new ScmCloudChainTransferContract();
            BeanUtils.copyProperties(s, scmCloudChainTransferContract);
            scmCloudChainTransferContract.setId(UUID.randomUUID().toString().replace("-", ""));
            scmCloudChainTransferContract.setTransferContractId(scmReceivablesTransferContract.getId());
            scmCloudChainTransferContractMapper.insert(scmCloudChainTransferContract);
        }
    }


    @Override
    public IPage<ScmReceivablesTransferApplicationVo> applicationList(TransferApplicationQueryPageDto transferApplicationQueryPageDto, Page<?> page) {
        //查询用户下有权限的应收账款转让流程任务
        TaskQuery query = new TaskQuery();
        query.setBusinessKey("receivables_transfer%");
        List<TaskVo> taskVoList = flowBaseCloudApi.findTasks(query, 0, Integer.MAX_VALUE).getResult().getRecords();
        List<String> applicationIds = new ArrayList<>();
        Map<String, TaskVo> map = new HashMap<>();
        if (oConvertUtils.listIsNotEmpty(taskVoList)) {
            //遍历任务根据任务中实例ID获取实例对象，并获取实例对象中的业务字段
            for (TaskVo task : taskVoList) {
                String instanceId = task.getInstanceId();
                ProInstanceVo proInstanceVo = flowBaseCloudApi.searchInstanceById(instanceId).getResult();
                String applicationId = proInstanceVo.getBusinessKey().split(":")[1];
                applicationIds.add(applicationId);
                map.put(applicationId, task);
            }
        }

        //获取当前用户信息和所在客户信息
        LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        ScmCusInfo cusInfoVo = scmCusInfoMapper.selectById(user.getCusNo());
        //查询状态为申请中和待签约的申请
        LambdaQueryWrapper<ScmReceivablesTransferApplication> queryWrapper = new LambdaQueryWrapper<>();
        if (!user.getOrganization().getType().equals(1)) {
            queryWrapper.select(ScmReceivablesTransferApplication::getId)
                    .eq(ScmReceivablesTransferApplication::getOwnerCusNo, cusInfoVo.getCusNo())
                    .or()
                    .eq(ScmReceivablesTransferApplication::getTransfereeCusNo, cusInfoVo.getCusNo())
                    .and(
                            wrapper -> wrapper.eq(ScmReceivablesTransferApplication::getStatus, ScmConstant.RECEIVABLES_TRANSFER_STATUS_INAPPLICATION)
                                    .or()
                                    .eq(ScmReceivablesTransferApplication::getStatus, ScmConstant.RECEIVABLES_TRANSFER_STATUS_TOBESIGNED)
                    );
        } else {
            queryWrapper.select(ScmReceivablesTransferApplication::getId)
                    .eq(ScmReceivablesTransferApplication::getStatus, ScmConstant.RECEIVABLES_TRANSFER_STATUS_INAPPLICATION)
                    .or()
                    .eq(ScmReceivablesTransferApplication::getStatus, ScmConstant.RECEIVABLES_TRANSFER_STATUS_TOBESIGNED)
                    .or()
                    .eq(ScmReceivablesTransferApplication::getStatus, ScmConstant.RECEIVABLES_TRANSFER_STATUS_FINISH);
        }

        List<ScmReceivablesTransferApplication> scmReceivablesTransferApplications = scmReceivablesTransferApplicationMapper.selectList(queryWrapper);
        for (ScmReceivablesTransferApplication s : scmReceivablesTransferApplications) {
            applicationIds.add(s.getId());
        }

        IPage<ScmReceivablesTransferApplicationVo> scmReceivablesTransferApplicationVoIPage = scmReceivablesTransferApplicationMapper.applicationList(applicationIds, transferApplicationQueryPageDto.getOwnerCusNo(), transferApplicationQueryPageDto.getTransfereeCusNo(), transferApplicationQueryPageDto.getApplyStartTime(), transferApplicationQueryPageDto.getApplyEndTime(), page);
        List<ScmReceivablesTransferApplicationVo> records = scmReceivablesTransferApplicationVoIPage.getRecords();
        for (ScmReceivablesTransferApplicationVo record : records) {
            //流程中的申请添加任务信息
            if (record.getStatus().equals(ScmConstant.RECEIVABLES_TRANSFER_STATUS_INPROCESS)) {
                TaskVo taskVo = map.get(record.getId());
                record.setTaskId(taskVo.getTaskId());
                record.setTaskName(taskVo.getTaskName());
                record.setInstanceId(taskVo.getInstanceId());
                record.setBusinessKey("receivables_transfer:" + record.getId());
            }
        }
        scmReceivablesTransferApplicationVoIPage.setRecords(records);
        scmReceivablesTransferApplicationVoIPage.setTotal(records.size());
        return scmReceivablesTransferApplicationVoIPage;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer delete(String id) {
        LambdaQueryWrapper<ScmCloudChainTransferApplication> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ScmCloudChainTransferApplication::getTransferApplyId, id);
        List<ScmCloudChainTransferApplication> chainApplications = scmCloudChainTransferApplicationMapper.selectList(queryWrapper);
        scmCloudChainTransferApplicationMapper.delete(queryWrapper);
        for (ScmCloudChainTransferApplication chainApplication : chainApplications) {
            ScmCloudChain scmCloudChain = scmCloudChainMapper.selectById(chainApplication.getChainNo());
            if (oConvertUtils.isEmpty(scmCloudChain.getOriginalChainNo())) {
                scmCloudChain.setStauts(ScmConstant.CHAIN_STATUS_NORMAL);
            } else {
                scmCloudChain.setStauts(ScmConstant.CHAIN_STATUS_SPLIT);
            }
            scmCloudChainMapper.updateById(scmCloudChain);
        }
        return scmReceivablesTransferApplicationMapper.deleteById(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteBatch(List<String> ids) {
        for (String id : ids) {
            delete(id);
        }
    }


}
